干货 | 基于信息论构建的测试解决方案——携程机票如何利用大数据提升测试效果?
作者简介
陈亮,携程机票BU高级测试经理,在软件服务端、前端的软件质量领域有多年的实战经验,喜欢钻研引入新技术,提升团队工作效率。
1948年信息论创始人香农博士在他的论文中指出,要想消除一个系统的不确定性,就必须使用信息。当你没有收集到足够多的信息时,不确定性就是一种客观事实,无论采用什么方法,都不可能消除。
近些年来国内业界讨论自动化测试的内容比较多,另一块测试数据信息的讨论却较少,然而测试数据质量决定了自动化的效果。本文将分享我们团队是如何通过提升测试数据质量,进而提升数据的自动化处理速度,最终提升测试效果的实践。
基于信息论的理论基础,我们提炼出做好软件测试的两个原则:
1、通过获取更多高质量的数据,提升测试覆盖率;
2、通过提升工程处理效率,提升数据处理效率;
目标:在有限的资源条件下做到最好,降低交付时的不确定性。
每次有大的功能点改动,上线后都会有不少问题。于是我找到这个功能的测试负责人,了解到每次发布会执行大约300条测试用例。
我:我们是否测试覆盖不足呢?
负责人:由于时间不足,我们只执行了大约一半的用例,如果下次给足够的时间,我确信能解决问题。
然后我们就这样尝试了一次。过了几天,他很沮丧的找到我。
负责人:上线仍然发现了一些问题,都是一些未考虑到的复杂场景,但是这些组合太多,很难全部测试一遍。
我:你说的这些复杂场景,我们必须要想办法解决,否则交付给用户时就会存在很大的不确定性。
接下来该怎么做?
首先,需要不断寻找新的数据信息,拓展自己的信息来源。
常用的信息源有PRD,设计文档,测试用例库等,但是这些都不能解决复杂场景组合的问题。携程的产品业务逻辑复杂,影响数据构成的因素非常多。以文中提及的功能A举例,存在10种影响因素,平均每个因素中存在3种情况,那么理论上数据复杂度可达到3的10次方59049种。
很显然,这个功能依靠几百个用例,肯定无法保证测试的覆盖率。
真实情况下,很多理论上的组合也并不存在,所以需要过滤掉这些不存在的组合,并且为剩下的组合进行排序。
具体怎么做呢?
1)为这些因素设计埋点,构建测试信息模型。
2)通过我们设计的一个信息爬虫去采集这些组合的数据,包含数据报文,实际使用次数等。一段时间内无使用的可过滤,剩余的组合根据使用量进行优先级排序,确定测试的优先级。
3)测试人员利用这些信息辅助决策,生成覆盖率更全面的测试用例数据集。
测试需要持久化使用的数据通常有两类:报文数据和数据库数据。
针对报文数据的持久化很简单,比较麻烦的是关联表数据的持久化。针对这类数据,我们的方案是为之创建数据镜像。
以携程机票订单数据表举例,涉及到的数据表有上千张,复杂数据的构建成本相当高,通过这个工具,用户可以为数据创建多个还原点,需要使用时一键还原即可。
实际使用场景中还需要解决日期自动平移等问题,工具都一一进行了处理,确保数据恢复后实际可用。目前支持SQLServer和MySQL两种数据库。
随着数据量级的提升,需要有一个服务平台能够帮助用户快速在大量数据中精确获取结果,于是我们开发了一套API和前端网页,用户可通过输入一个或多个关键字,获取需要的信息,前端页面的使用模式类似于我们常见的搜索引擎。
实际使用中,还有以下问题需要解决。
数据排序
我们为数据设计了一套打分机制,根据该数据的创建时间,使用次数,用户反馈,来源渠道进行综合评分,根据评分高低进行排序。
数据锁定
为防止同一份数据多人使用互相影响,系统提供了数据锁定&解锁的功能。
搜索关键字提示
为帮助用户输入更精准的关键字条件,系统支持关键字联想推荐,辅助用户确定搜索条件
数据问题解决了,接下来就要考虑提升工程效率,应对数据量100倍的增长。
具体在工程设计时考虑以下几个方面:
高效性:降低单个用例耗时,并采用分布式多并发执行方式。
可扩展性:支持两个层面:测试数据和用例的快速扩展和测试页面的低成本接入扩展。
低维护成本:维护成本不会随着使用量的增长而线性增加,应保持基本稳定。
具体来看下服务端和前端的解决方案:
服务端的测试成本主要是两块:测试报文数据和测试验证点设计
思路回到上文中的信息爬虫,针对各种场景组合,测试模式如下:
爬虫可以帮助我们获取到服务和服务内部所依赖服务的所有报文信息(请求报文+返回报文)
准备两套测试环境,一套部署基线版本,一套部署待测试版本
为还原当时的场景,将依赖服务的返回报文动态配置到Mock服务器,保证环境的稳定。
使用爬虫获取到的请求报文对部署好的两套环境分别发送请求,获取到返回报文和服务内部调用依赖服务的请求报文
进行比对分析,生成测试报告。为提升报告分析效率,需要对报告内容进行聚合,并忽略设定可忽略的部分。
集成到持续集成中。每当有代码签入时,即可触发一个小规模的流量回放测试,代码发布前,触发一个大规模组合的流量回放测试,实现问题的快速反馈。
前端的测试难度相对服务端复杂很多,主要是体现在依赖众多,检查点不易判断。根据传统的逐个元素获取的检查方式,成本太高,且很难判断样式,字体等问题。
为了做好前端的自动化测试,我们认为需要遵循以下几点:
使用上文中信息爬虫获取的各种场景组合的数据,丰富测试覆盖面
将前端页面展示锁依赖的服务端数据返回进行动态mock,保证环境稳定
流程性页面功能支持schema url直接访问,减少测试前序耗时
使用图像比对的方式进行检查点判断,降低检查成本,增加检查覆盖面
监听页面发送和接收的报文数据,进行报文层的检查
提升单用例的执行速度
支持分布式并发执行
测试报告的可读性
参照以上几点,我们设计了一套图像比对系统,使用信息爬虫获取的数据,帮助测试人员进行前端测试。
1)前端的样式经常会有一些调整,有时调整一下字体,一些样式就会导致页面中的元素展示产生很大变化。如果我们想忽略这种变化,只关心展示的内容是否正确,是否有一种方式可以快速实现呢?
我们想到了图像文字识别,通过这种技术,可以直接告知用户具体的不同点,用户不必看图,减少了报告分析者的分析工作量。
2)前端有的模块是已知的不同点,比如说:广告轮播模块,针对这类部分可以设置截图时自动忽略这个部分。
3)比对结果智能分类:针对不同数据发现的同一类问题,系统会根据不同点进行自动聚合分类,只在报告中展示一个样例,使用者可自行决定是否需要查看其它数据
4)智能忽略:使用者在分析报告过程中,如果发现一些不同点是正常的,可设置忽略,系统下次对比时就会自动将这类内容标识为可忽略。
使用无头浏览器测试方案
在我们的SnapDiff平台中,我们使用了Chrome开发团队去年新推出的PuppeteerAPI。
Puppeteer是一个Nodejs的库,支持调用Chrome的API来操纵Web,相比较Selenium或是PhantomJs,它最大的特点就是它的操作Dom可以完全在内存中进行模拟既在V8引擎中处理而不打开浏览器,而且关键是这个是Chrome团队在维护,会拥有更好的兼容性和前景。
分布式并发
平台首先会将任务分发到不同的测试服务器,然后在每台服务器上多线程并发执行,通过这种方式,整体耗时大幅减少。
支持自助接入
对于非定制类的常规测试需求,用户可自助创建测试任务,通过在配置中心里配置对比页面的url,div,运行规则,报告收件人等即可实现接入。
支持Job自助启动
测试任务的执行控制可自助操作完成
不能帮助我们找到系统问题的测试框架都不完美,说明这个框架只是解决了一部分问题。所以我们在设计这套系统的时候,是抱着能够尽量多的发现问题的目的去做的。
我们希望在测试的每个阶段都能够把工具引入进来,而不是只在某一个阶段。
所以工具可以支持开发同学自测,测试同学做新功能的测试,也可以做最后的回归测试,正因如此,它能够帮助我们发现更多的系统问题,在我写这篇文章过去的30天内,这套系统帮助我们发现了60+个系统bug,未来我们还会不断优化,让这个系统发挥更大的作用。
使用这套系统,许多测试执行的工作都交给了计算机,测试人员更多的关注于构建测试数据模型,分析测试报告,定位问题发生原因。在测试设计和报告分析这两块工具更多的是起到了辅助的角色,未来我们也会在这两个领域进行更深入的探索。
【推荐阅读】